<?php
declare(strict_types=1);

namespace WebApp\lib\db\mysql;

use ServerApp\lib\core\ServerStation;
use WebApp\lib\db\AbstractTable;

/**
 * Class Table
 * @package txz\common\third_lib\model\lib
 */
class MysqlTable extends AbstractTable
{
    /**
     * @var NormalDriver|NormalDriverV2|CoDriver
     */
    public $driver;

    public function __construct(IMysqlConfig $config, $server_name, $table_name, $pre = '', $suffix = '')
    {
        parent::__construct($server_name, $config->getDbName(), $table_name, $pre, $suffix);
        if (defined("ENV_PHP_FPM") && ENV_PHP_FPM) {
            $this->driver = new NormalDriver($config);
        } else {
            if (ServerStation::$wId !== null) {
                $this->driver = new CoDriver($config);
            } else {
                $this->driver = new NormalDriverV2($config);
            }
        }
    }

    /**
     * @param array $need
     * @param array $where
     * @param string $group
     * @param string $sort
     * @param string $limit
     * @return mixed
     */
    public function getObjArr($need = [], $where = [], $group = '', $sort = '', $limit = '')
    {
        return $this->getPool()->exec(
            $this->driver->getObjArr("{$this->db_name}.{$this->table_name}", ...func_get_args())
        ) ?: [];
    }

    /**
     * @param string $sql
     * @param array $data
     * @return mixed
     */
    public function getObjArrBySql(string $sql, $data=[])
    {
        return $this->getPool()->exec(
            $this->driver->getObjArrBySql(...func_get_args())
        );
    }

    public function removeObj($where = [])
    {
        return $this->getPool()->exec(
            $this->driver->removeObj("{$this->db_name}.{$this->table_name}", ...func_get_args())
        );
    }

    /**
     * @param array $need
     * @param array $where
     * @param string $group
     * @param string $sort
     * @return mixed
     */
    public function getObj($need = [], $where = [], $group = '', $sort = '')
    {
        return $this->getPool()->exec(
            $this->driver->getObj("{$this->db_name}.{$this->table_name}", ...func_get_args())
        );
    }

    public function updateObj(array $data, array $where)
    {
        return $this->getPool()->exec(
            $this->driver->updateObj("{$this->db_name}.{$this->table_name}", ...func_get_args())
        );
    }

    public function addObj(array $data = [])
    {
        return $this->getPool()->exec(
            $this->driver->addObj("{$this->db_name}.{$this->table_name}", ...func_get_args())
        );
    }


    public function execute(string $sql)
    {
        return $this->getPool()->exec(
            $this->driver->execute($sql)
        );
    }


    public function getOne(&$row, $select, array $where = [], $group = '', $sort = '')
    {
        return $this->getPool()->exec(
            $this->driver->getObjV1($row, "{$this->db_name}.{$this->table_name}", $select, $where, $group, $sort)
        );
    }

    public function getAll(&$rows, $select, array $where = [], string $group = '', $sort = '', array $limit = [])
    {
        return $this->getPool()->exec(
            $this->driver->getObjArrV1($rows, "{$this->db_name}.{$this->table_name}", $select, $where, $group, $sort, $limit)
        );
    }

    /**
     * @return null
     */
    public function getTableName()
    {
        return $this->table_name;
    }

    /**
     * @param null $table_name
     */
    public function setTableName($table_name): void
    {
        $this->table_name = $table_name;
    }

    /**
     * @return null
     */
    public function getDbName()
    {
        return $this->db_name;
    }

    /**
     * @param null $db_name
     */
    public function setDbName($db_name): void
    {
        $this->db_name = $db_name;
    }

    /**
     * @return MysqlPool
     */
    function getPool(): MysqlPool
    {
        if (!$this->pool) {
            $this->pool = new MysqlPool($this->driver);
        }
        return  $this->pool;
    }
}
